#pragma once

namespace Loading{
	enum textureChannel {TC_DIFFUSE,TC_SPECULAR,TC_BUMP};

	struct DataHeader{
		unsigned int numModels;
		unsigned int numSubMeshes;
		unsigned int numEffects;
		unsigned int numTextures;
		unsigned int numVertLayouts;
		unsigned int numVertLayoutElements;

		unsigned int numJoints;
		unsigned int numControllers;
		unsigned int numAnimationSources;
		unsigned int numAnimations;
		unsigned int numAnimationSamplers;
		unsigned int numAnimationClips;
		unsigned int numAnimationFloats;
		unsigned int numAnimationUints;

		unsigned int verticeBufferSize;
		unsigned int indexBufferSize;
	};

	struct outputEffectData{
		outputEffectData(){
			for(int i=0; i<3; i++){
				m_emissive[i] = 0;
				m_ambient[i] = 0;
				m_diffuse[i] = 0;
				m_specular[i] = 0;
				m_transparent[i] = 0;
			}

			m_emissive[3] = 1;
			m_ambient[3] = 1;
			m_diffuse[3] = 1;
			m_specular[3] = 1;
			m_transparent[3] = 1;
			m_transparency = 1;
			m_shininess = 0;

			memset(m_name,'\0',60);
			memset(m_textureIds,-1,sizeof(int)*10);
		}

		char m_name[60];

		unsigned int m_id;
		int m_textureIds[10];

		float 	m_emissive[4],
				m_ambient[4],
				m_diffuse[4],
				m_specular[4],
				m_transparent[4],
				m_transparency,
				m_shininess;
	};

	struct outputTextureData{
		outputTextureData(){
			memset(m_filename,'\0',30);
		}

		unsigned int m_id;
		char m_filename[30];
		textureChannel m_channel;
	};

	struct outputModelHeader{
		outputModelHeader(){
			memset(m_subMeshIds,-1,sizeof(int)*20);	
		}

		int m_subMeshIds[20];
		int m_controllerId;
		// 0: -x 
		// 1: x 
		// 2: -y
		// 3: y
		// 4: -z
		// 5: z
		float m_bounds[6];
	};

	struct outputSubMesh{
		unsigned int m_id;

		unsigned int m_indOffset;
		unsigned int m_numInds;
		unsigned int m_indDataStride;
		
		unsigned int m_vertOffset;
		unsigned int m_vertDataStride;
		unsigned int m_numVerts;

		unsigned int m_effectId;
		unsigned int m_vertLayoutId;
	};

	struct outputVertLayoutElement{
		outputVertLayoutElement(){
			memset(m_semantic,'\0',10);
		}

		char m_semantic[10];
		unsigned int m_stride;
	};

	struct outputVertLayout{
		outputVertLayout(){
			memset(m_elementIds,-1,sizeof(int)*10);
		}

		int m_elementIds[10];
	};

	struct outputJoint{
		outputJoint(){
			memset(m_name,'\0',20);
			memset(m_bindInvMatrix,0,sizeof(float)*62);
			m_parentId = -1;
			m_numChilds = 0;
			m_childIdOffset = 0;
			m_bakedTransform = false;

			m_rotateX[0] = 1.0;
			m_rotateY[1] = 1.0;
			m_rotateZ[2] = 1.0;
			
			m_orientX[0] = 1.0;
			m_orientY[1] = 1.0;
			m_orientZ[2] = 1.0;
		}

		bool m_bakedTransform;
		char m_name[20];
		float m_bindInvMatrix[16];
		float m_transformMatrix[16];

		float m_translate[3];
		float m_scale[3];

		float m_rotateX[4];
		float m_rotateY[4];
		float m_rotateZ[4];

		float m_orientX[4];
		float m_orientY[4];
		float m_orientZ[4];
		
		int m_parentId;
		unsigned int m_numChilds;
		unsigned int m_childIdOffset;
	};

	struct outputController{
		outputController(){
			memset(m_name,'\0',30);
		}

		char m_name[30];
		float m_bindMatrix[16];

		unsigned int m_numJoints;
		unsigned int m_jointOffset;
	};

	struct outputAnimationSource{
		enum AnimationSourceType{AST_FLOAT,AST_STRING,AST_UINT};
		enum AnimationSourceSemantic{ASS_INPUT,ASS_OUTPUT,ASS_INTERPOLATION,ASS_IN_TANGENT,ASS_OUT_TANGENT};
	
		unsigned int 	m_dataOffset,
						m_dataCount,
						m_stride;

		AnimationSourceSemantic m_semantic;
		AnimationSourceType m_type;
	};

	struct outputAnimationSampler{
		enum SamplerInterpolationType{SIT_BEIZER,SIT_STEP,SIT_LINEAR,SIT_CARDINAL,SIT_HERMITE,SIT_BSPLINE};

		unsigned int 	m_numSources,
						m_sourceOffset;
	};

	struct outputAnimation{
		enum TargetComponent{	TC_TRANSLATE_X,
								TC_TRANSLATE_Y,
								TC_TRANSLATE_Z,
								
								TC_SCALE_X,
								TC_SCALE_Y,
								TC_SCALE_Z,
		
								TC_ORIENTATION_X,
								TC_ORIENTATION_Y,
								TC_ORIENTATION_Z,
		
								TC_VISIBILITY,
								TC_TRANSFORM};

		unsigned int m_samplerId;
		unsigned int m_targetJoint;
		TargetComponent m_targetComponent;
	};

	struct outputAnimationClip{
		outputAnimationClip(){
			memset(m_name,'\0',30);
		}

		unsigned int 	m_numAnimIds,
						m_animIdOffset;

		char 	m_name[30];
		float 	m_start,
				m_end;
	};
}